package com.scorpio.baselibrary.utils;

import android.text.TextUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 时间工具包
 * Created by 包子 on 2017/4/25.
 */
public class TimeUtil {
    public static SimpleDateFormat formatter = new SimpleDateFormat();
    public static final String DATE_PATTERN_FULL = "yyyy-MM-dd";
    public static final String TIME_PATTERN_FULL = "yyyy-MM-dd HH:mm";
    //一天的毫秒
    public static final long ONE_DAY_TIME = 24 * 60 * 60 * 1000;
    //一小时
    public static final long ONE_HOUR_TIME = 60 * 60 * 1000;
    public static final long TIME_INIT_HOUR = ONE_HOUR_TIME * 8;

    /**
     * 获取UNIX几小时之后的时间
     *
     * @param hr 小时
     * @return
     */
    public static long getAssignTime(int hr) {
        long time = System.currentTimeMillis() / 1000;
        time += (hr * 3600);
        return time;
    }

    //获取系统时间字符串
    public static String getSyatemTimeText() {
        return getSyatemTimeText(TIME_PATTERN_FULL);
    }

    //获取系统日期
    public static String getSyatemDateText() {
        return getSyatemTimeText(DATE_PATTERN_FULL);
    }

    //获取系统时间字符串
    public synchronized static String getSyatemTimeText(String pattern) {
        Date date = new Date();
        formatter.applyPattern(pattern);
        return formatter.format(date);
    }

    //时间转变毫秒
    public synchronized static long formatTimeConvertMsec(String time) {
        if (time == null || time.isEmpty()) return 0;
        formatter.applyPattern(TIME_PATTERN_FULL);
        try {
            return formatter.parse(time).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    //时间转变毫秒
    public synchronized static long formatTimeConvertMsec(String pattern, String time) {
        formatter.applyPattern(pattern);
        try {
            return formatter.parse(time).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    //日期转变毫秒
    public synchronized static long formatDateConvertMsec(String date) {
        if (TextUtils.isEmpty(date)) return 0;
        formatter.applyPattern(DATE_PATTERN_FULL);
        try {
            return formatter.parse(date).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static String formatMsecConvertTime(long time) {
        return formatMsecConvertTime(TIME_PATTERN_FULL, time);
    }

    //毫秒转变时间
    public synchronized static String formatMsecConvertTime(String pattern, long time) {
        return formatDateConvertTime(pattern, new Date(time));
    }

    //Date转变时间
    public synchronized static String formatDateConvertTime(String pattern, Date date) {
        formatter.applyPattern(pattern);
        return formatter.format(date);
    }

    //获取昨天日期
    public static String getYesterdayDate() {
        long time = TimeUtil.formatDateConvertMsec(TimeUtil.getSyatemDateText());
        return TimeUtil.formatMsecConvertTime(time - TimeUtil.ONE_DAY_TIME);
    }

    //获取明天日期
    public static String getTomorrowDate() {
        long time = TimeUtil.formatDateConvertMsec(TimeUtil.getSyatemDateText());
        return TimeUtil.formatMsecConvertTime(time + TimeUtil.ONE_DAY_TIME);
    }

    //获取周一的日期
    public synchronized static String getThisWeekMonday() {
        Calendar c = Calendar.getInstance(Locale.CHINA);
        c.setFirstDayOfWeek(Calendar.MONDAY);
        //当前时间，貌似多余，其实是为了所有可能的系统一致
        c.setTimeInMillis(System.currentTimeMillis());
        c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        formatter.applyPattern(DATE_PATTERN_FULL);
        return formatter.format(c.getTime());
    }

    /**
     * 获取指定月份 第一天
     *
     * @param amount 0当月 -1上个月 1下个月
     * @return
     */
    public synchronized static String getAppointMonthFirstDay(String pattern, int amount) {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, amount);
        c.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天
        formatter.applyPattern(pattern);
        return formatter.format(c.getTime());
    }

    public static String getAppointMonthFirstDay(int amount) {
        return getAppointMonthFirstDay(DATE_PATTERN_FULL, amount);
    }

    /**
     * 获取指定年月的第一天
     *
     * @param year  年份
     * @param month 月份
     * @return
     */
    public synchronized static String getAppointYearMonthFirstDay(int year, int month) {
        formatter.applyPattern(DATE_PATTERN_FULL);
        return formatter.format(getAppointYearMonthFirstDayTime(year, month));
    }

    public synchronized static long getAppointYearMonthFirstDayTime(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date firstDate = cal.getTime();//当前月第一天
        return firstDate.getTime();
    }

    /**
     * 获取指定年月的最后一天
     *
     * @param year  年份
     * @param month 月份
     * @return
     */
    public synchronized static String getAppointYearMonthFinallyDay(int year, int month) {
        formatter.applyPattern(DATE_PATTERN_FULL);
        return formatter.format(getAppointYearMonthFinallyDayTime(year, month));
    }

    public synchronized static long getAppointYearMonthFinallyDayTime(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month);
        cal.set(Calendar.DAY_OF_MONTH, -1);
        Date lastDate = cal.getTime();//当前月最后一天
        return lastDate.getTime() + ONE_DAY_TIME;
    }

    //获取某一年有多少天
    public static int getAppointTearDayCount(int year) {
        int days;//某年(year)的天数
        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {//闰年的判断规则
            days = 366;
        } else {
            days = 365;
        }
        return days;
    }

    /**
     * 指定时间转为毫秒
     *
     * @param time 12:00
     * @return
     */
    public static long getAppointHourMinuteTime(String time) {
        String[] dates = time.split(":");
        long t = Integer.valueOf(dates[0]) * 1000 * 60 * 60;
        t += Integer.valueOf(dates[1]) * 1000 * 60;
        return t;
    }

    /**
     * 获取指定年月 的天数
     *
     * @param year  年份
     * @param month 月份
     * @return
     */
    public static int getAppointYearMonthDayCount(int year, int month) {
        String date1 = TimeUtil.getAppointYearMonthFirstDay(year, month);
        String date2 = TimeUtil.getAppointYearMonthFinallyDay(year, month);
        long t1 = TimeUtil.formatDateConvertMsec(date2);
        long t2 = TimeUtil.formatDateConvertMsec(date1);
        return (int) ((t1 - t2) / TimeUtil.ONE_DAY_TIME + 1);
    }

    //获取指定年月 的天数
    public static int getAppointDateDayCount(String date) {
        String[] dates = date.split("-");
        int year = Integer.valueOf(dates[0]);
        int month = Integer.valueOf(dates[1]);
        return getAppointYearMonthDayCount(year, month);
    }

    //获取指定年月 的天数
    public static int getAppointDateDayCount(long time) {
        return getAppointDateDayCount(TimeUtil.formatMsecConvertTime(time));
    }

    /**
     * 获取指定一周的 开始时间
     *
     * @param time
     * @return
     */
    public static long getSpecifyDateStartWeek(Date time) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(time);
        // 判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        cal.setFirstDayOfWeek(Calendar.MONDAY);// 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        int day = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        return cal.getTime().getTime();
    }

    /**
     * 转换毫秒为时分秒
     *
     * @param time 时间/毫秒
     * @return
     */
    public static int[] convertTimeToHours(long time) {
        int hr = (int) (time / TimeUtil.ONE_HOUR_TIME);
        int min = (int) (time % TimeUtil.ONE_HOUR_TIME) / 1000 / 60;
        int sec = (int) (time % TimeUtil.ONE_HOUR_TIME) % 60 / 1000;
        return new int[]{hr, min, sec};
    }
}
